package edu.harvard.s3xyback;

import edu.harvard.s3xyback.S3xyBack;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Random;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class AESKeyFactory {

	
	private static final int AES_KEYSIZE = 256; // bits
	private static final String AES_STRING = "AES/CBC/PKCS5Padding";
	private static final String AES_KEY_STRING = "PBKDF2WithHmacSHA1";
	private static final int AES_KEY_ITER = 1024*6;
	
	
	public static byte[] generateKey(String pass, String keyFile, String saltFile) {
	try{
		// generate salt
		Random r = new SecureRandom();
		byte[] salt = new byte[16];
		r.nextBytes(salt);
		
		// generate aes key
		SecretKeyFactory factory = SecretKeyFactory.getInstance(AES_KEY_STRING);
		KeySpec spec = new PBEKeySpec(pass.toCharArray(), salt, AES_KEY_ITER, AES_KEYSIZE);
		SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");

		// save key to file
		FileOutputStream fout_key = new FileOutputStream(keyFile);
		fout_key.write(secret.getEncoded());
		fout_key.close();
		
		// save salt to file
		FileOutputStream fout_salt = new FileOutputStream(saltFile);
		fout_salt.write(salt);
		fout_salt.close();
		
		return secret.getEncoded();
	} catch (Exception e) {
		throw new RuntimeException(e);
	}
	}
	
	public static SecretKey readKey(String keyFile) {
		return readKey(new File(keyFile));
	}
	
	public static SecretKey readKey(File keyFile) {
	try {
		
		FileInputStream fin_key = new FileInputStream(keyFile);
		byte[] keyBytes = new byte[AES_KEYSIZE/8];
		fin_key.read(keyBytes);
		return new SecretKeySpec(keyBytes, "AES");
		
		
	} catch (Exception e) {
		throw new RuntimeException(e);
	}	
	}
	
	public static void main(String[] args) throws Exception {
		byte[] key_out = generateKey("blah blah blahxxxxxxxxxxxx", "C:\\Users\\ayoung01\\Dropbox\\s3xyback\\java\\src\\edu\\harvard\\s3xyback\\.aws_key", "C:\\Users\\ayoung01\\Dropbox\\s3xyback\\java\\src\\edu\\harvard\\s3xyback\\.aws_salt");
		//generateKey("blah blah blahxxxxxxxxxxxx", "/Users/jonathon/.aws_key_2", "/Users/jonathon/.aws_salt_2");
		//byte[] key_in = readKey("/Users/jonathon/.aws_key_1").getEncoded();

		//System.out.println(key_in.length);
		//System.out.println(key_in.equals(key_out));
		
	}
	
}
